<template>
  <div class="waterfall-container" ref="waterfall">
    <!-- 没有帖子时显示的空状态 -->
    <div v-if="posts.length === 0" class="empty-state">
      <el-icon class="empty-icon"><Document /></el-icon>
      <p>暂时没有动态</p>
    </div>

    <PostCard
      v-for="post in sortedPosts"
      :key="post._id || post.id"
      :post="post"
      @click="$emit('post-click', post)"
    />
    <div ref="loadingTrigger" class="loading-trigger" v-if="posts.length > 0">
      <div v-if="isLoading" class="loading-indicator">
        <el-icon class="loading-icon"><Loading /></el-icon>加载更多...
      </div>
      <!-- 没有更多帖子时显示 -->
      <div v-else-if="!hasMore" class="end-message">
        没有更多动态了
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
import PostCard from './PostCard.vue';
import { Loading, Document } from '@element-plus/icons-vue';

const props = defineProps({
  posts: {
    type: Array,
    required: true
  },
  sortBy: {
    type: String,
    default: 'createdAt' // 默认按创建时间排序
  },
  sortOrder: {
    type: String,
    default: 'desc' // 默认降序排列（最新的在前）
  },
  columns: {
    type: Number,
    default: 0 // 默认为0，表示自动计算列数
  },
  hasMore: {
    type: Boolean,
    default: true // 是否有更多数据可加载
  }
});

const waterfall = ref(null);
const columnCount = ref(4); // 默认4列
const loadingTrigger = ref(null);
const isLoading = ref(false);

// 发出的事件，现在包括加载更多事件
const emit = defineEmits(['post-click', 'load-more']);

// 根据提供的排序属性和顺序对帖子进行排序
const sortedPosts = computed(() => {
  const sorted = [...props.posts];

  // 如果是按时间属性排序
  if (props.sortBy === 'createdAt') {
    return sorted.sort((a, b) => {
      const dateA = new Date(a.createdAt || 0);
      const dateB = new Date(b.createdAt || 0);
      return props.sortOrder === 'desc' ? dateB - dateA : dateA - dateB;
    });
  }

  // 如果是按其他属性排序
  return sorted.sort((a, b) => {
    const valueA = a[props.sortBy] || 0;
    const valueB = b[props.sortBy] || 0;
    return props.sortOrder === 'desc' ? valueB - valueA : valueA - valueB;
  });
});

// 计算适合父容器的列数
function calculateColumns() {
  if (!waterfall.value) {
    // console.warn('[PostWaterfall] 容器引用不存在');
    return;
  }

  // 如果提供了指定的列数，直接使用指定值
  if (props.columns > 0) {
    columnCount.value = props.columns;
    waterfall.value.style.gridTemplateColumns = `repeat(${props.columns}, 1fr)`;
    // console.log(`[PostWaterfall] 使用指定的列数: ${props.columns}`);
    return;
  }

  const containerWidth = waterfall.value.offsetWidth;
  // console.log(`[PostWaterfall] 容器实际宽度: ${containerWidth}px`);

  // 检查是否有效的宽度
  if (containerWidth <= 0) {
    // console.warn('[PostWaterfall] 检测到容器宽度为0或负值，使用父元素宽度');
    // 尝试获取父元素宽度
    const parentWidth = waterfall.value.parentElement?.offsetWidth || window.innerWidth;
    setColumnsByWidth(parentWidth);
    return;
  }

  setColumnsByWidth(containerWidth);
}

// 根据宽度设置列数的辅助函数
function setColumnsByWidth(width) {
  let newColumnCount;

  if (width >= 1400) {
    newColumnCount = 5;
  } else if (width >= 1000) {
    newColumnCount = 4;
  } else if (width >= 700) {
    newColumnCount = 3;
  } else if (width >= 400) {
    newColumnCount = 2;
  } else {
    newColumnCount = 1;
  }

  // 只有当列数发生变化时才更新样式
  if (newColumnCount !== columnCount.value) {
    columnCount.value = newColumnCount;
    if (waterfall.value) {
      waterfall.value.style.gridTemplateColumns = `repeat(${newColumnCount}, 1fr)`;
      // console.log(`[PostWaterfall] 根据容器宽度(${width}px)设置列数为: ${newColumnCount}`);
    }
  }
}

// 计算所有卡片的高度
function resizeAllWaterfallItems() {
  // 先计算容器的列数
  calculateColumns();

  // 只选择当前组件内的卡片元素
  if (!waterfall.value) return;
  const cardItems = waterfall.value.querySelectorAll('.waterfall-item');

  cardItems.forEach(item => {
    const cardContent = item.querySelector('.card-content');
    if (cardContent) {
      const contentHeight = cardContent.getBoundingClientRect().height;
      const rowGap = 16; // 与CSS中的grid-gap相匹配
      const rowHeight = 1; // grid-auto-rows 设置为1px
      const rowSpan = Math.ceil((contentHeight + rowGap) / (rowHeight + rowGap));
      item.style.gridRowEnd = `span ${rowSpan}`;
    }
  });
}

// 处理窗口大小变化的去抖动函数
let resizeTimeout = null;
function handleResize() {
  if (resizeTimeout) {
    clearTimeout(resizeTimeout);
  }

  resizeTimeout = setTimeout(() => {
    calculateColumns();
    resizeAllWaterfallItems();
  }, 200);
}

// 创建监听滚动的函数
let scrollTimeout = null;
function handleScroll() {
  if (scrollTimeout) {
    clearTimeout(scrollTimeout);
  }

  scrollTimeout = setTimeout(() => {
    if (!loadingTrigger.value || !props.hasMore || isLoading.value) return;

    const triggerRect = loadingTrigger.value.getBoundingClientRect();
    const viewportHeight = window.innerHeight;

    // 当触发元素进入视口底部200px范围内时加载更多
    if (triggerRect.top < viewportHeight + 200) {
      // 触发加载更多
      loadMore();
    }
  }, 100);
}

// 加载更多数据的函数
function loadMore() {
  if (isLoading.value || !props.hasMore) return;

  isLoading.value = true;
  emit('load-more');
}

// 重置加载状态
function resetLoadingState() {
  isLoading.value = false;
}

// 监听columns属性变化
watch(() => props.columns, (newVal) => {
  // console.log(`[PostWaterfall] columns属性变化: ${newVal}`);
  nextTick(() => {
    calculateColumns();
    setTimeout(resizeAllWaterfallItems, 50);
  });
}, { immediate: true });

// 在挂载完成后设置监听
onMounted(() => {
  // 确保先应用列数设置
  // console.log('[PostWaterfall] 组件挂载完成');

  // DOM可能还没有完全渲染，延迟执行初始化
  setTimeout(() => {
    calculateColumns();
    resizeAllWaterfallItems();

    // 监听窗口大小变化，使用去抖动函数
    window.addEventListener('resize', handleResize);
    // 监听滚动事件
    window.addEventListener('scroll', handleScroll);
    // console.log('[PostWaterfall] 已添加窗口大小变化监听');
  }, 300);
});

// 在卸载前清除事件监听
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  window.removeEventListener('scroll', handleScroll);
  if (resizeTimeout) {
    clearTimeout(resizeTimeout);
  }
  if (scrollTimeout) {
    clearTimeout(scrollTimeout);
  }
  // console.log('[PostWaterfall] 组件卸载，已清理事件监听');
});

// 监听posts变化，当数据更新时重新计算布局
watch(() => props.posts, (newPosts) => {
  // console.log(`[PostWaterfall] 帖子数据更新，数量: ${newPosts?.length || 0}`);

  // 数据更新后，等待DOM更新完成再重新计算
  nextTick(() => {
    setTimeout(() => {
      calculateColumns();
      resizeAllWaterfallItems();
    }, 100);
  });
}, { deep: true });

// 监听容器宽度变化（用MutationObserver实现）
onMounted(() => {
  // 设置一个ResizeObserver监听容器大小变化
  if (typeof ResizeObserver !== 'undefined' && waterfall.value) {
    const resizeObserver = new ResizeObserver(entries => {
      for (const entry of entries) {
        if (entry.target === waterfall.value) {
          // console.log(`[PostWaterfall] 检测到容器大小变化，新宽度: ${entry.contentRect.width}px`);
          handleResize();
        }
      }
    });

    resizeObserver.observe(waterfall.value);

    // 在组件卸载时停止观察
    onBeforeUnmount(() => {
      resizeObserver.disconnect();
      // console.log('[PostWaterfall] ResizeObserver已断开');
    });
  }
});

// 暴露方法以便父组件可以手动触发重新计算
defineExpose({
  resizeAllWaterfallItems,
  calculateColumns,
  resetLoadingState
});
</script>

<style scoped>
/* 瀑布流容器样式 */
.waterfall-container {
  display: grid;
  /* 设置默认的网格模板，确保容器有初始宽度 */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 1px;
  grid-gap: 16px;
  width: 100%;
  box-sizing: border-box;
  min-width: 300px; /* 确保最小宽度 */
  padding: 1px;
}

.loading-trigger {
  grid-column: 1 / -1;
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
}

.loading-indicator {
  display: flex;
  align-items: center;
  color: #ffffff;
  font-size: 14px;
}

.loading-icon {
  animation: rotating 2s linear infinite;
  margin-right: 8px;
}

.end-message {
  color: #909399;
  font-size: 14px;
  text-align: center;
}

.empty-state {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 200px;
  color: #909399;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.5;
}

@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
